Skip to content

Retire the MkDocs blog and redirect its URLs to freeshard.net - #12

Open
ClaydeCode wants to merge 1 commit into
mainfrom
feature/blog-redirects
Open

Retire the MkDocs blog and redirect its URLs to freeshard.net#12
ClaydeCode wants to merge 1 commit into
mainfrom
feature/blog-redirects

Conversation

@ClaydeCode

Copy link
Copy Markdown
Contributor

Retires the MkDocs blog and redirects every URL it used to publish to the new location on freeshard.net. Second half of #4; the first half is FreeshardBase/landing-page#16.

What's here

  • docs/blog/posts/**, docs/blog/index.md and docs/blog/.authors.yml deleted.
  • The blog plugin and the Blog nav section removed from mkdocs.yml.
  • 20 static index.html redirect stubs added under docs/blog/, one per URL the plugin used to publish: 13 posts, 5 archive years, page/2/ and the index. MkDocs copies non-markdown files through verbatim, so they land at exactly the old paths.
  • docs/index.md linked to the blog page by source path, which --strict rejects once the page is gone; it now links to the new location.
  • agents.md updated: plugin list, structure, nav section count, and a new "Retired Blog" section explaining what the stubs are and why they must not be deleted.

Why the redirects are not what the issue specifies

Issue #4 step 4 calls for 301s via a Traefik redirectregex middleware on the docs router, in the shape used for activate.freeshard.net. That is not available here:

  • docs.freeshard.net is a CNAME to freeshardbase.github.io and responds with server: GitHub.com. It is GitHub Pages, and GH Pages cannot issue arbitrary redirects.
  • activate.freeshard.net resolves to Azure and does sit behind Traefik — which is why the pattern exists there. It does not transfer to docs.

So each stub is an instant meta refresh plus a rel=canonical and a visible link. Google documents that it interprets an instant meta refresh as a permanent redirect, while still recommending a server-side redirect wherever one is possible. Putting docs behind a proxy that can answer real 301s is the upgrade path if link equity turns out to matter — worth a follow-up issue, not a blocker at 13 posts.

Why teardown and redirects are one commit

The issue sequences these as "redirects first, remove the plugin once they're live". That works for a proxy-level redirect, which intercepts the request. A static stub replaces the page, so it cannot coexist with the post it stands in for. Both have to land together, or the old URLs either keep serving the old blog or 404.

The old URL list

Taken from a local mkdocs build, not from the source directory names — that matters:

  • Two posts were published on a different day than the directory they live in (2024-09-03_going_paperless published 2024-09-10, 2025-04-28_rebrand_and_source_public published 2025-04-29). The live URL uses the frontmatter date.
  • Every slug derives from the post's H1, not its directory name (going-paperless-with-paperless-on-portal, not going_paperless).

The new posts keep those exact slugs, so the map is one-to-one.

Verification

  • uv run mkdocs build --strict passes.
  • All 20 stubs confirmed present in public/blog/ at exactly the paths the plugin used to generate, compared against the pre-change build output.
  • The Google redirects doc cited above was fetched (200).

Merge order

Merge FreeshardBase/landing-page#16 first. These stubs point at freeshard.net/en/blog/..., which does not exist until that one is deployed. Merging this first means the old URLs redirect to 404s.

Follow-on

Unblocks the Zensical migration (#10), which was waiting on the Material blog plugin going away — Zensical does not implement it (zensical/backlog#30). Note for whoever does that work: the stubs are plain static files under docs/, and the generator swap must keep copying them through, or all 20 old URLs 404.

Recommended reading order

  1. mkdocs.yml — plugin and nav removal
  2. docs/index.md — the one dangling link
  3. agents.md — the "Retired Blog" section
  4. docs/blog/**/index.html — the stubs (20 near-identical files)
  5. the docs/blog/posts/** deletions (bulk)

The blog now lives at freeshard.net/<lang>/blog/ as an Astro content
collection (documentation#4, landing-page PR). This removes it here and
puts a redirect in place of every URL it used to publish.

The stubs and the teardown have to land together. Issue #4 sequences
them as "redirect first, remove the plugin once redirects are live",
which assumed a Traefik `redirectregex` middleware on the docs router,
in the shape used for activate.freeshard.net. That is not available
here: docs.freeshard.net is a CNAME to freeshardbase.github.io, so it is
served by GitHub Pages, which cannot issue arbitrary redirects.
activate.freeshard.net resolves to Azure and does sit behind Traefik,
which is why the pattern exists there - it does not transfer.

So the redirects are 20 static `index.html` stubs under docs/blog/,
which MkDocs copies through verbatim to exactly the paths the blog
plugin used to occupy: 13 posts, 5 archive years, page/2 and the index.
Because a stub replaces the page rather than intercepting the request,
it cannot go live before the post it replaces is gone - hence one
commit. The old paths were taken from a local `mkdocs build`, not from
the source directory names: two posts published on a different day than
their directory is named for, and every slug derives from the post title.

Each stub is an instant `meta refresh` plus `rel=canonical` and a
visible link. Google documents that it reads an instant meta refresh as
a permanent redirect, while still recommending a server-side redirect
where one is possible:
https://developers.google.com/search/docs/crawling-indexing/301-redirects
Putting docs behind a proxy that can answer real 301s remains the
upgrade path if the link equity turns out to matter.

docs/index.md linked to the blog page by source path, which strict mode
rejects once the page is gone; it now links to the new location.

Unblocks the Zensical migration (#10), which was waiting on the Material
`blog` plugin disappearing.
@ClaydeCode
ClaydeCode requested a review from max-tet August 4, 2026 04:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant